package com.wxw.BaseLibrary.http.soap;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.wxw.BaseLibrary.db.DBTool;
import com.wxw.BaseLibrary.http.*;
import com.wxw.BaseLibrary.tool.DES3;
import com.wxw.BaseLibrary.tool.SystemTool;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;

/**
 * Created by david on 2016/5/10.
 */
public class SoapRequestTask<T> implements IRequestTask {
    private RequestManager manager = null;
    private RequestMessage message = null;
    private Request<T> request = null;
    private static final Object HANDLER_LOCK = new Object();

    private static Handler sRequestHandler = null;
    private RequestCompletedListener requestCompletedListener = null;
    private SoapListener soapListener = null;
    private List<SoapRequestParam> params = null;
    private boolean isEncrypt = false;

    public SoapRequestTask(Request<T> request) {
        this.request = request;
    }

    @Override
    public void setRequestCompletedListener(RequestCompletedListener requestCompletedListener) {
        this.requestCompletedListener = requestCompletedListener;
    }

    @Override
    public void setSoapListener(SoapListener soapListener) {
        this.soapListener = soapListener;
    }

    @Override
    public void init(RequestManager manager, RequestMessage message) {
        this.manager = manager;
        this.message = message;
        if (!"".equals(this.message.RequestContent)) {
            try {
                params = new Gson().fromJson(this.message.RequestContent, new TypeToken<List<SoapRequestParam>>(){}.getType());
            } catch (Exception e) {
                e.printStackTrace();
                params = null;
            }
        }
    }


    @Override
    public void startTask() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                runTask();
            }
        }).start();
    }

    public boolean isEncrypt() {
        return isEncrypt;
    }

    public void setEncrypt(boolean encrypt) {
        isEncrypt = encrypt;
    }

    private void runTask() {
        while (!SystemTool.isOpenNetwork(manager.getContext())) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                Log.e("ReqTask", "Exception:" + e.getMessage());
            }
        }
        final SoapThreadPoster startThread = new SoapThreadPoster(0, soapListener);
        startThread.onStart();
        getPosterHandler().post(startThread);
        String s = "";
        Response<T> response = null;
        RequestMethod requestMethod = RequestMethod.GET;
        try {
            SoapExecutor executor = null;
            int sp, ep;
            switch (message.httpMethod) {
                case GET:
                    executor = GetSoapExecutor.getInstance();
                    break;
                case POST:
                    requestMethod = RequestMethod.POST;
                    executor = PostSoapExecutor.getInstance();
//                    HashMap<String, Object> param = createHttpPostParam(params, isEncrypt);
//                    if (message.Pause)return;
//                    s = SoapTool.doPost(message.RequestService, message.RequestMethod, param);
//                    if (message.Pause)return;
//                    sp = s.indexOf(">") + 1;
//                    ep = s.indexOf("</");
//                    try {
//                        if (sp>1 && ep>sp)
//                            s = s.substring(sp, ep);
//                        if (isEncrypt)
//                            s = DES3.des3DecodeECB(s);
//                        if (message.Pause)return;
//                    } catch (Exception ex) {
//                        Log.e("ReqTask", "Exception:" + ex.getMessage());
//                        message.Status = RequestMessageStatus.Error;
//                        message.ResponseContent = ex.getMessage() + "[" + s + "]";
//                    }
                    break;
                case PUT:
                    break;
                case DELETE:
                    break;

                default:
                    break;
            }

            response = executor.executeRequest(request);
            if (message.Status == RequestMessageStatus.Submit) {
                message.Status = RequestMessageStatus.Complete;
                message.ResponseContent = s;
            }
        } catch (Exception e) {
            Log.e("ReqTask", "Exception:" + e.getMessage());
            message.Status = RequestMessageStatus.Error;
            message.ResponseContent = e.getMessage() + ";S:" + s;
            response = new SoapResponse<T>(request.url(), requestMethod, request.getTag(), 0, e);
        }
        final SoapThreadPoster finishThread = new SoapThreadPoster(0, soapListener);
        finishThread.onFinished();
        getPosterHandler().post(finishThread);
        message.update(DBTool.getInstance());

        final SoapThreadPoster responseThread = new SoapThreadPoster(0, soapListener);
        finishThread.onResponse(response);
        getPosterHandler().post(responseThread);
        if (requestCompletedListener != null) {
            requestCompletedListener.onCompleted(this, message);
        }
    }

    private Handler getPosterHandler() {
        synchronized (HANDLER_LOCK) {
            if (sRequestHandler == null) {
                sRequestHandler = new Handler(Looper.getMainLooper());
            }
        }
        return sRequestHandler;
    }

    public static String createHttpGetParam(List<SoapRequestParam> params, boolean isEncrypt) {
        String args = "";
        for (SoapRequestParam param : params) {
            switch (param.getType()) {
                case 0:
                    String s = param.getValue().toString();
                    if (isEncrypt) {
                        try {
                            s = DES3.des3EncodeECB(s);
                        } catch (Exception ex) {
                            s = param.getValue().toString();
                        }
                    }
                    args += param.getKey()+"="+s+"&";
                    break;
                case 1:
                    break;
                case 2:
                    break;
                default:
                    break;
            }
        }
        if (args.endsWith("&")) {
            args = args.substring(0, args.length()-1);
        }
        return args;
    }

    public static HashMap<String, Object> createHttpPostParam(List<SoapRequestParam> params, boolean isEncrypt) {
        HashMap<String, Object>  hashMap = new HashMap<String, Object>();
        if (params!=null && params.size()>0) {
            if (isEncrypt) {
                encryptParam(params);
            }
            for (SoapRequestParam param : params) {
                hashMap.put(param.getKey(), param.getValue());
            }
        }
        return hashMap;
    }

    public static void encryptParam(List<SoapRequestParam> params) {
        for (SoapRequestParam param : params) {
            switch (param.getType()) {
                case 0:
                    String s = param.getValue().toString();
                    try {
                        s = DES3.des3EncodeECB(s);
                    } catch (Exception ex) {
                        s = param.getValue().toString();
                    }
                    param.setValue(s);
                    break;
                case 1:
                    try {
                        param.setValue(DES3.des3EncodeECB(DES3.SECURITY_KEY, (byte[])param.getValue()));
                    } catch (Exception e) {

                    }
                    break;
                case 2:
                    try {
                        File file = new File(param.getValue().toString());
                        FileInputStream inputStream = new FileInputStream(file);
                        if (inputStream != null) {
                            int length = inputStream.available();
                            byte[] buffer = new byte[length];
                            inputStream.read(buffer);
                            param.setValue(buffer);
                        }
                        param.setValue(DES3.des3EncodeECB(DES3.SECURITY_KEY, (byte[])param.getValue()));
                    } catch (Exception e) {

                    }
                    break;
                default:
                    break;
            }
        }
    }
}
